package com.chennan.redis.domain.distributedlockservice;

import com.chennan.redis.domain.service.RedisServiceComplete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author chennan
 * @createTime 2021年07月23日 14:03:00
 */
@Service
public class SimpleDistributedLockServiceImpl implements SimpleDistributedLockService {
    public static final Logger LOGGER = LoggerFactory.getLogger(SimpleDistributedLockServiceImpl.class);
    public static final Integer REDISKEY_EXPIRE = 60;
    @Autowired
    private RedisServiceComplete redisService;

    public SimpleDistributedLockServiceImpl() {
    }

    @Override
    public <T> T doWithLock(String bizLockName, LockCallback<T> lockCallback) {
        String redisKey = String.format("SimpleLock:lockName:%s", bizLockName);
        String redisValue = UUID.randomUUID().toString();

        T var5;
        try {
            while(!this.redisService.setNX(redisKey, redisValue, REDISKEY_EXPIRE)) {
                LOGGER.info("have not got the lock,sleep 500 milliseconds...");
                TimeUnit.MILLISECONDS.sleep(500L);
            }

            var5 = lockCallback.doBiz();
        } catch (Throwable var14) {
            LOGGER.info("operate redis error in doWithLock", var14);
            throw new RuntimeException(var14);
        } finally {
            try {
                if (redisValue.equals(this.redisService.get(redisKey))) {
                    this.redisService.del(redisKey);
                }
            } catch (Throwable var13) {
                LOGGER.info("operate redis error in doWithLock finally block", var13);
            }

        }

        return var5;
    }

    @Override
    public <T> T doWithLockNoBlock(String bizLockName, Integer lockTime, LockCallback<T> lockCallback) {
        String redisKey = String.format("SimpleLock:lockName:%s", bizLockName);
        String redisValue = UUID.randomUUID().toString();

        T var6;
        try {
            if (lockTime == null) {
                lockTime = REDISKEY_EXPIRE;
            }

            if (!this.redisService.setNX(redisKey, redisValue, lockTime)) {
                var6 = null;
                return var6;
            }

            var6 = lockCallback.doBiz();
        } catch (Throwable var16) {
            LOGGER.info("operate redis error in doWithLock", var16);

            throw new RuntimeException(var16);
        } finally {
            try {
                if (redisValue.equals(this.redisService.get(redisKey))) {
                    this.redisService.del(redisKey);
                }
            } catch (Throwable var15) {
                LOGGER.info("operate redis error in doWithLock finally block", var15);
            }

        }

        return var6;
    }
}

